﻿/*******************************************************************
Copyright (c) 2011 이재범

*  Permission is hereby granted, free of charge, to any person
*  obtaining a copy of this software and associated documentation
*  files (the "Software"), to deal in the Software without
*  restriction, including without limitation the rights to use,
*  copy, modify, merge, publish, distribute, sublicense, and/or sell
*  copies of the Software, and to permit persons to whom the
*  Software is furnished to do so, subject to the following
*  conditions:
* 
*  The above copyright notice and this permission notice shall be
*  included in all copies or substantial portions of the Software.
* 
*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
*  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
*  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
*  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
*  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
*  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
*  OTHER DEALINGS IN THE SOFTWARE.
*******************************************************************/

#include <vector>
#include <fstream>
#include <string>
#include <iostream>
#pragma once
using namespace std;

template <typename T>
class Dictionary
{
	static const int max_string_size = 10000;
private:
	vector<T> list;

public:
	Dictionary(){}
	Dictionary(string file_location)
	{
		ifstream data_in(file_location, ios::binary);
		string temp_str;

		while (data_in.good())
		{
			getline(data_in, temp_str);

			if(!data_in.good())
				break;
			if(!temp_str.empty())
				temp_str.erase(temp_str.end() - 1);
			list.push_back(temp_str);
		}
	}
	void push_back(T data)
	{
		list.push_back(data);
	}

	// find 는 찾지 못하면 -1 을 리턴하고, 찾으면 이에 해당하는
	// index 를 리턴한다. 
	int find(T data)
	{
		vector<T>::size_type i;
		for(i = 0; i < list.size(); i++)
		{
			if(list[i] == data)
				return i;
		}

		return -1;
	}
	int size()
	{
		return list.size();
	}

	bool empty()
	{
		return list.empty();
	}
	friend ostream& operator<< <Dictionary<T> >(ostream& os, const Dictionary<T>& dic);

	void erase(int i)
	{
		list.erase(list.begin() + i);
	}
	void print()
	{
		for(int i = 0; i < list.size(); i ++)
			cout << list[i] << endl;
	}
	T& operator[] (const int index) { return list[index]; }
};	

template <typename T>
ostream& operator<< (ostream& os, const Dictionary<T>& dic)
{
	for(vector<T>::size_type i = 0; i < dic.list.size(); i++)
		os << dic.list[i] << endl;

	return os;
}

template<>
class Dictionary <basic_string<TCHAR>>
{
	static const int max_string_size = 10000;
private:
	vector<basic_string<TCHAR>> list;

public:
	Dictionary()
	{

	}
	Dictionary(string file_location)
	{
		wifstream data_in(file_location);

		wchar_t str[max_string_size];
		while (data_in.good())
		{
			data_in.getline(str, max_string_size);
			basic_string<TCHAR> word(str);

			if(word.empty() && !data_in.good())
				break;
			list.push_back(word);
		}
	}
	void push_back(basic_string<TCHAR> data)
	{
		list.push_back(data);
	}

	bool empty()
	{
		return list.empty();
	}

	void erase(int i)
	{
		list.erase(list.begin() + i);
	}
	// find 는 찾지 못하면 -1 을 리턴하고, 찾으면 이에 해당하는
	// index 를 리턴한다. 
	int find(basic_string<TCHAR> data)
	{
		vector<basic_string<TCHAR>>::size_type i;
		for(i = 0; i < list.size(); i++)
		{
			if(list[i] == data)
				return i;
		}

		return -1;
	}
	int size()
	{
		return list.size();
	}
	void print()
	{
		for(vector<basic_string<TCHAR>>::size_type i = 0; i < list.size(); i ++)
			wcout << list[i] << endl;
	}
	//friend ostream& operator<< (ostream& os, const Dictionary& dic);
	basic_string<TCHAR>& operator[] (const int index) { return list[index]; }
};

/*
template<>
ostream& operator<< (ostream& os, const Dictionary<basic_string<TCHAR>>& dic)
{
for(int i = 0; i < dic.list.size(); i++)
os << dic.list[i] << endl;

return os;
}*/